package com.iwhalecloud.citybrain.flow.platform.manager.infrastructure.repository;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.model.FlowMessageConfigVo;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.model.notice.NoticeInfo;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.model.notice.common.MsgContent;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.model.notice.common.PushUserId;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.model.notice.request.MessageCenterRequest;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.model.notice.request.RequestMsg;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.model.notice.response.MessageCenterResponse;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.model.notice.response.ResponseResult;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.repository.FlowMessageConfigRepository;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.repository.NoticeRepository;
import com.iwhalecloud.citybrain.flow.platform.manager.infrastructure.mapper.NoticeTemplateDAO;
import com.iwhalecloud.citybrain.flow.platform.manager.application.utils.HttpUtils;
import com.iwhalecloud.citybrain.flow.platform.manager.application.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

/**
 * @author fenghongjian
 * @description
 * @date 2019/7/12 9:35
 */
@Service
public class NoticeRepositoryImpl implements NoticeRepository {

    private final Logger logger = LoggerFactory.getLogger(NoticeRepositoryImpl.class);

    @Value("${message.center.push.url:}")
    private String messageCenterPushUrl;

    @Autowired
    private NoticeTemplateDAO noticeTemplateDAO;

    @Autowired
    private FlowMessageConfigRepository flowMessageConfigRepository;

    /**
     * 为了测试-预先通知类型和消息源注册后消息源ID的映射
     */
    private static HashMap<String, String> TypeMap;
    /**
     * 微信-纯文本消息,后面这个需要消息中心提供最新值
     */
    private final static String MESSAGE_TYPE_0111 = "0111";

    /**
     * 系统端消息，文本消息
     */
    private final static String MESSAGE_TYPE_0601 = "0601";

    private final static String SEND_SUCCESS_CODE = "1";

    private final static String SEND_SUCCESS = "Y";

    private final static String SEND_FAIL = "N";

    /**
     * contents的参数，这条推送的类型，有如下几种类型：
     * TEXT，
     * IMAGE，
     * VOICE，
     * VIDEO；
     * 分别对应文本，图片，音频，视频；多媒体的格式只支持url格式，
     * 需要预先确认该url是否可访问，对于不可访问的资源，将会推送失败。
     * 类型必须严格遵守以上几种格式。
     */
    private static String MESSAGE_CONTENT_TYEP_TEXT = "TEXT";

    private static String MESSAGE_CENTER_RESPONSE_DATAS = "datas";

    static {
        TypeMap = new HashMap<>();
        TypeMap.put("SYSTEM", "808ebd7982934138b2ac894ddb9d8577");
        TypeMap.put("DINGDING", "808ebd7982934138b2ac894ddb9d8577");
        TypeMap.put("SMS", "808ebd7982934138b2ac894ddb9d8577");
        TypeMap.put("MAIL", "808ebd7982934138b2ac894ddb9d8577");
        TypeMap.put("POLICE_SERVICE", "808ebd7982934138b2ac894ddb9d8577");
    }

    @Async
    @Override
    public void sendNotice(List<NoticeInfo> list) {
        sendNoticeToMessageCenter(list);
    }

    @Override
    public void sendNoticeToMessageCenter(List<NoticeInfo> list) {
        for (NoticeInfo info : list) {
            sendNoticeMessage(info);
        }
    }

    private String sendNoticeMessage(NoticeInfo noticeInfo) {
        String msgSourceId = resolveMsgSourceId(noticeInfo);
        if (StringUtils.isEmpty(msgSourceId)) {
            return SEND_FAIL;
        }

        MessageCenterRequest mcq = new MessageCenterRequest();
        mcq.setMsgSourceId(msgSourceId);
        mcq.setMessageType(MESSAGE_TYPE_0601);
        List<RequestMsg> msgList = new ArrayList<>();
        mcq.setMsgList(msgList);

        RequestMsg msg = new RequestMsg();
        msg.setMsgTitle(convertNullToString(noticeInfo.getTitle()));
        msg.setMsgDescription(convertNullToString(noticeInfo.getName()));
        msgList.add(msg);
        List<MsgContent> contents = new ArrayList<>();
        msg.setContents(contents);
        List<PushUserId> pushUserIds = new ArrayList<>();
        msg.setPushUserIds(pushUserIds);

        MsgContent content = new MsgContent();
        content.setType(MESSAGE_CONTENT_TYEP_TEXT);
        content.setContent(convertNullToString(noticeInfo.getContent()));
        contents.add(content);

        PushUserId pushUserId = new PushUserId();
        pushUserId.setKey(convertNullToString(noticeInfo.getAccount()));
        pushUserId.setName(convertNullToString(noticeInfo.getAccountName()));
        pushUserIds.add(pushUserId);
        String json = JSON.toJSONString(mcq);

        logger.info("调用消息中心接口，请求参数：" + json);
        String result = HttpUtils.sendHttpPost(messageCenterPushUrl, json);
        logger.info("调用消息中心接口，返回参数：" + result);

        JSONObject jsonObject = JSON.parseObject(result);
        JSONArray datas = null;
        if (jsonObject != null) {
            datas = jsonObject.getJSONArray(MESSAGE_CENTER_RESPONSE_DATAS);
        }
        String status = SEND_FAIL;
        if (datas != null) {
            List<MessageCenterResponse> messageCenterResponseList = JSONObject.parseArray(datas.toJSONString(), MessageCenterResponse.class);
            for (MessageCenterResponse mcr : messageCenterResponseList) {
                List<ResponseResult> responseResults = mcr.getResults();
                Integer pushResultCode = responseResults.get(0).getPushResultCode();
                String pushResultDescription = responseResults.get(0).getPushResultDescription();
                logger.info("推送结果编码：{}，推送结果描述：{}", pushResultCode, pushResultDescription);
                if (SEND_SUCCESS_CODE.equals(pushResultCode.toString())) {
                    //更新发送是否成功状态
                    status = SEND_SUCCESS;
                }
            }
        }
        noticeTemplateDAO.updateSendStatus(noticeInfo.getRuNoticeChannelId(), status);
        return status;
    }

    private String resolveMsgSourceId(NoticeInfo noticeInfo) {
        FlowMessageConfigVo messageConfig = flowMessageConfigRepository.getConfigByChannelAndSystemCode(noticeInfo.getType(), noticeInfo.getSystemCode());
        if (Objects.nonNull(messageConfig)) {
            return messageConfig.getMsgSourceId();
        }
        return null;
    }

    @Override
    public String reSendNoticeMessage(NoticeInfo noticeInfo) {
        if (noticeInfo == null) {
            return SEND_FAIL;
        }
        return sendNoticeMessage(noticeInfo);
    }

    private String convertNullToString(String str) {
        if (StringUtils.isEmpty(str)) {
            return "";
        }
        return str;
    }
    //    @Override
    //    public void sendSameNoticeTypeToMessageCenter(List<NoticeInfo> list, String title, String name, String type, String content) {
    //
    //        MessageCenterRequest mcq = new MessageCenterRequest();
    //        mcq.setMsgSourceId(TypeMap.get(type));
    //        mcq.setMessageType(MESSAGE_TYPE_0111);
    //        List<RequestMsg> msgList = new ArrayList<>();
    //        mcq.setMsgList(msgList);
    //
    //        RequestMsg msg = new RequestMsg();
    //        msgList.add(msg);
    //        msg.setMsgTitle(title);
    //        msg.setMsgDescription(name);
    //        List<MsgContent> contents = new ArrayList<>();
    //        msg.setContents(contents);
    //        List<PushUserId> pushUserIds = new ArrayList<>();
    //        msg.setPushUserIds(pushUserIds);
    //
    //        MsgContent msgContent = new MsgContent();
    //        msgContent.setType(MESSAGE_CONTENT_TYEP_TEXT);
    //        msgContent.setContent(content);
    //        contents.add(msgContent);
    //
    //        for (NoticeInfo info : list) {
    //            PushUserId pushUserId = new PushUserId();
    //            pushUserId.setKey(info.getAccount());
    //            pushUserId.setName(info.getAccountName());
    //            pushUserIds.add(pushUserId);
    //        }
    //
    //        String json = JSON.toJSONString(mcq);
    //
    //        logger.info("调用消息中心接口，请求参数：" + json);
    //        String result = HttpUtils.sendHttpPost(messageCenterPushUrl, json);
    //        logger.info("调用消息中心接口，返回参数：" + result);
    //
    //        JSONObject jsonObject = JSON.parseObject(result);
    //        JSONArray datas = jsonObject.getJSONArray(MESSAGE_CENTER_RESPONSE_DATAS);
    //        List<MessageCenterResponse> messageCenterResponseList = JSONObject.parseArray(datas.toJSONString(), MessageCenterResponse.class);
    //        for (MessageCenterResponse mcr : messageCenterResponseList) {
    //            List<ResponseResult> responseResults = mcr.getResults();
    //            for (ResponseResult rr : responseResults) {
    //
    //                Integer pushResultCode = rr.getPushResultCode();
    //                String pushResultDescription = rr.getPushResultDescription();
    //                logger.info("推送结果编码：{}，推送结果描述：{}", pushResultCode, pushResultDescription);
    //
    //                List<ResultReceiver> resultReceivers = rr.getReceivers();
    //                for (ResultReceiver receiver : resultReceivers) {
    //                    logger.info("--- 接收人ID：{}，接收人姓名：{}", receiver.getReceiverId(), receiver.getReceiverName());
    //                }
    //            }
    //        }
    //    }
}
